package com.mjw.tender.configuration;

import lombok.AllArgsConstructor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.cache.RedisCacheConfiguration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializationContext;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;

import java.time.Duration;

/**
 * @author mjw
 * @date 2020/3/29
 * Redis 配置类
 */
@Configuration
@AllArgsConstructor
public class RedisConfig {
	private final RedisConnectionFactory factory;

	/**
	 * 配置 @Cacheable 的序列化以及过期时间
	 * @param connectionFactory
	 * @return
	 */
	@Bean
	public RedisCacheManager cacheManager(RedisConnectionFactory connectionFactory){
		Duration live = Duration.ofDays(1);//缓存过期时间
		RedisCacheConfiguration configuration = RedisCacheConfiguration.defaultCacheConfig()
				.entryTtl(live)
				.serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(keySerializer()))
				.serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(valueSerializer()))
				.disableCachingNullValues();//查询结果为null时不存到缓存中
		RedisCacheManager redisCacheManager = RedisCacheManager.builder(connectionFactory)
				.cacheDefaults(configuration)
				.transactionAware() //支持事务
				.build();
		return redisCacheManager;
	}

	/**
	 * 配置 redisTemplate 序列化
	 * @return
	 */
	@Bean
	public RedisTemplate<String, Object> redisTemplate() {
		RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
		redisTemplate.setKeySerializer(keySerializer());
		redisTemplate.setHashKeySerializer(keySerializer());
		redisTemplate.setValueSerializer(valueSerializer());
		redisTemplate.setHashValueSerializer(valueSerializer());
		redisTemplate.setConnectionFactory(factory);
		return redisTemplate;
	}

	private RedisSerializer<String> keySerializer(){
		return new StringRedisSerializer();
	}

	private RedisSerializer<Object> valueSerializer(){
		return new GenericJackson2JsonRedisSerializer();
	}

}
